/**
* Copyright (c) By zengqh.
*
* This program is just for fun or demo, in the hope that it  
* will be useful, you can redistribute it and/or modify freely.
*
* Time: 2012/07/17
* File: App.cpp
* Blog: http://www.cnblogs.com/zengqh/
**/

#define MOVE_DISTANCE		(0.1f)
#include "App.h"

App::App()
: _camera(NULL)
, _move_distance(0.0f)
{

}

App::~App()
{

}

void App::Initalize()
{
	Dimension2Du dimension(800, 480);

	_device = createDevice(DT_OPENGL, dimension);
}

void App::Loop()
{
	while(_device->run())
	{
		_render_system->beginScene();
		_scene_mgr->render();
		_render_system->endScene();

		_device->swap();
	}
}

void App::UnInitialize()
{

}

bool App::frameStarted(const FrameEvent& frameEvent)
{
	_input_system->capture();

	/*
	_camera->move(_move_distance);
	*/

	return true;
}

bool App::frameEnded(const FrameEvent& frameEvent)
{
	return true;
}

bool App::mouseMoved(const OIS::MouseEvent &arg)
{
	/*
	if(_camera)
	{
		_camera->yaw(-0.5f * arg.state.X.rel);
		_camera->pitch(0.5f * arg.state.Y.rel);
	}
	*/

	return true;
}

bool App::mousePressed(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
{
	arg;
	return true;
}

bool App::mouseReleased(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
{
	arg;
	return true;
}

bool App::keyPressed(const OIS::KeyEvent &arg)
{
	if(arg.key == OIS::KC_W) _move_distance = MOVE_DISTANCE;
	if(arg.key == OIS::KC_S) _move_distance = -MOVE_DISTANCE;
	return true;
}

bool App::keyReleased(const OIS::KeyEvent &arg)
{
	if(arg.key == OIS::KC_W || arg.key == OIS::KC_S)
	{
		_move_distance = 0.0f;
	}

	return true;
}

void App::setupContent()
{
	_scene_mgr = _device->getSceneManager();
	_render_system = _device->getRenderSystem();
	_input_system = _device->getInputSystem();

	_input_system->addKeyListener(this, "keyListener");
	_input_system->addMouseListener(this, "mouseListner");
	_render_system->addFrameListener(this);

	Texture* top = _render_system->createTexture("../Media/Skybox/top.jpg", false);
	Texture* bottom = _render_system->createTexture("../Media/Skybox/bottom.jpg", false);
	Texture* left = _render_system->createTexture("../Media/Skybox/left.jpg", false);
	Texture* right = _render_system->createTexture("../Media/Skybox/right.jpg", false);
	Texture* front = _render_system->createTexture("../Media/Skybox/front.jpg", false);
	Texture* back = _render_system->createTexture("../Media/Skybox/back.jpg", false);

	SkyboxSceneNode* skybox = new SkyboxSceneNode(NULL, _scene_mgr,
		-1, 0, top, bottom, left, right, front, back);

	_scene_mgr->addSkyboxSceneNode(skybox);

	_camera = new CameraSceneNode(NULL, _scene_mgr, -1, 0);

	_camera->lookAt(glm::vec3(0.0f, 0.0f, 8.0f), glm::vec3(0.0f, 0.0f, 0.0f),
		glm::vec3(0.0f, 1.0f, 0.0f));

	const Recti& view_port = _render_system->getViewport();

	_camera->setPerspectiveFov(60.0f, 
		(f32)view_port._right_bottom.x / (f32)view_port._right_bottom.y,
		0.1f, 50000.0f);

	_scene_mgr->setActiveCamera(_camera);

	
}

int main()
{
	App app;

	app.Initalize();
	app.setupContent();
	app.Loop();
	app.UnInitialize();

	return 0;
}